package com.mccken.demo.io.nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.StandardOpenOption;

import lombok.extern.slf4j.Slf4j;

/**
 * @program: mccken-collect
 * @description:
 * @author: mccken
 * @create: 2023-11-06 12:57
 **/
@Slf4j
public class NIO_7 {

	public static void main(String[] args) throws IOException {
		// 读文件
//		channelDemo1();
		// 写文件
//		channelDemo2();
		// 超大文件传输
		channelDemo3();
		
	}

	private static void channelDemo3() throws FileNotFoundException {
		
		try(
				FileChannel outChanel = new FileInputStream("/Users/mccken/文档/temp/111.png").getChannel();
		        FileChannel targetChanel = new FileOutputStream("/Users/mccken/文档/temp/111-2.png").getChannel()
		) {
			long size = outChanel.size();
			// 超过2G的文件，transferTo一次性还不能完全传输过去，所以需要for循环
			for (long left = size; left > 0;) {
				long position = size - left;
				System.out.println("position:" + position + " left:" + left);
				left -= outChanel.transferTo(position, left, targetChanel);
				System.out.println("tppp");
				// 打印  targetChanel 对象的大小
				System.out.println(targetChanel.size());
			}
			
			
		} catch (IOException e) {
			System.out.println("tttt");
			throw new RuntimeException(e);
		}
		System.out.println("112313465");
	}

	private static void channelDemo2() throws IOException {
		
		//获取输出流
		FileOutputStream outputStream = new FileOutputStream("/Users/mccken/文档/sublime/1.txt");
		//根据输出流获得一个"写"权限的通道
		FileChannel outChannel = outputStream.getChannel();

		ByteBuffer outBuffer = ByteBuffer.allocate(50);
		log.info("outChannel:{}", outChannel.position());
		outChannel.write(outBuffer);
		log.info("outChannel:{}", outChannel.position());
		outBuffer.flip();
		log.info("outBuffer:{}, {}, {}", outBuffer.limit(), outBuffer.position(), outBuffer.capacity());
		log.info("outChannel:{}", outChannel.position());
		log.info("outBuffer:{}", new String(outBuffer.array(), 0, outBuffer.limit()));
//		获得一个有指定内容的缓冲区
		ByteBuffer source = ByteBuffer.wrap("HelloWorld".getBytes(StandardCharsets.UTF_8));
		//将缓冲区内容写入到通道
		outChannel.write(source);
		log.info("source:{}", new String(source.array(), 0, source.limit()));

//		//获取输入流
		FileInputStream fileInputStream = new FileInputStream("/Users/mccken/文档/sublime/1.txt");
//		//根据输入流获得一个"读"权限的通道
		FileChannel inChannel = fileInputStream.getChannel();
		log.info("inChannel:{}", inChannel.position());
		//获得一个空内容的缓冲区
		ByteBuffer target = ByteBuffer.allocate(50);
		log.info("target:{}, {}, {}", target.position(), target.limit(), target.capacity());
		//将通道中的内容读到缓冲区
		inChannel.read(target);
		log.info("target:{}, {}, {}", target.position(), target.limit(), target.capacity());
		//转换缓冲区读写模式
		target.flip();
		log.info("target:{}, {}, {}", target.position(), target.limit(), target.capacity());
		//读出缓冲区中的内容
		log.info("target:{}", new String(target.array(), 0, target.limit()));

		//关闭资源
		outChannel.close();
		inChannel.close();
	}

	/**
	 * 通道写
	 */
	public static void channelDemo1() throws IOException {
		FileChannel fileChannel = FileChannel.open(new File("/Users/mccken/文档/sublime/1.txt").toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE);

		ByteBuffer wrap = ByteBuffer.wrap("hello".getBytes());
		ByteBuffer target = ByteBuffer.allocate(100);

		System.out.println("fileChannel.position(): " + fileChannel.position());
		fileChannel.write(wrap);
		System.out.println("fileChannel.position(): " + fileChannel.position());
		fileChannel.position(0);
		fileChannel.read(target);

		target.flip();
		wrap.flip();
		System.out.println(new String(target.array()));
		
		target.clear();
		wrap.clear();
		fileChannel.close();
	}
}
